// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const { ccclass } = cc._decorator;

@ccclass
export default abstract class CollisionUnit extends cc.Component {

    private static allUnits: (CollisionUnit | null)[] = [];

    protected static test(rect: cc.Rect, source: CollisionUnit): boolean {
        const uid = source.collisionUnitId;
        return this.allUnits.filter(unit => (!!unit && uid !== unit.collisionUnitId)).some(function (unit: CollisionUnit) {
            return cc.Intersection.rectRect(rect, unit.myRect);
        });
    }
    protected static getList(rect: cc.Rect, source: CollisionUnit): CollisionUnit[] {
        const uid = source.collisionUnitId;
        return this.allUnits.filter(unit => (
            !!unit &&
            uid !== unit.collisionUnitId &&
            cc.Intersection.rectRect(rect, unit.myRect)
        ));
    }

    protected add(c: CollisionUnit): number {
        const uid = c.collisionUnitId;
        if (CollisionUnit.allUnits.some(item => !!item && uid === item.collisionUnitId)) {
            return;
        }

        this.collisionUnitId = CollisionUnit.allUnits.length;

        const id = CollisionUnit.allUnits.length;
        CollisionUnit.allUnits.push(c);
        return id;
    }





    protected myRect: cc.Rect;
    private collisionUnitId: number;

    public abstract shotten(level: number): void;

    public destroy(): boolean {
        if (!this.isValid) {
            return false;
        }

        CollisionUnit.allUnits[this.collisionUnitId] = null;
        this.node.destroy();
        return super.destroy();
    }

    protected testCollision(rect: cc.Rect) {
        return CollisionUnit.test(rect, this);
    }
    protected getCollisionList(rect: cc.Rect) {
        return CollisionUnit.getList(rect, this);
    }
}
